package org.linlinjava.litemall.admin.job;

import org.linlinjava.litemall.db.dao.*;
import org.linlinjava.litemall.db.dao.divided.AgedmallInfoPromoteUserSettlementMapper;
import org.linlinjava.litemall.db.dao.divided.AgedmallUserPromoteSettlementMapper;
import org.linlinjava.litemall.db.dao.divided.LitemallUserOrderItemMapper;
import org.linlinjava.litemall.db.dao.divided.LitemallUserPromoteOrderItemMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.util.*;
import org.linlinjava.litemall.db.vo.divided.AgedmallPromoteTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户分成定时结算
 * @author huangfei
 * @create 2021-12-17 16:45
 */
@Component
public class DividedIntoSettlementTask {

    private static final Logger logger = LoggerFactory.getLogger(DividedIntoSettlementTask.class);

    @Resource
    private AgedmallUserPromoteSettlementMapper agedmallUserPromoteSettlementMapper;

    @Resource
    private AgedmallCustomTemplateMapper agedmallCustomTemplateMapper;

    @Resource
    private AgedmallCustomGoodsMapper agedmallCustomGoodsMapper;

    @Resource
    private LitemallUserPromoteOrderItemMapper litemallUserPromoteOrderItemMapper;

    @Resource
    private LitemallGoodsMapper litemallGoodsMapper;

    @Resource
    private AgedmallPromoteSettlementMapper agedmallPromoteSettlementMapper;

    @Resource
    private AgedmallPromoteUserSettlementMapper agedmallPromoteUserSettlementMapper;

    @Resource
    private AgedmallLeaseGoodsReturnRecordMapper agedmallLeaseGoodsReturnRecordMapper;

    @Resource
    private LitemallUserOrderItemMapper litemallUserOrderItemMapper;

    @Resource
    private AgedmallPromoteAccountMapper agedmallPromoteAccountMapper;

    @Resource
    private AgedmallUserInfoMapper agedmallUserInfoMapper;

    @Resource
    private AgedmallAgentFinanceDetailMapper agedmallAgentFinanceDetailMapper;

    @Resource
    private AgedmallInfoPromoteUserSettlementMapper agedmallInfoPromoteUserSettlementMapper;


   @Scheduled(cron = PromoteScheduled.PROMOTE_REAL_TIOME_ORDER_05) // 间隔5秒执行
   @Transactional
    public void execute() {
       logger.info("系统开启定时任务检查获取推广订单");
        List<AgedmallPromoteTemplate> agedmallPromoteSettlementList = agedmallUserPromoteSettlementMapper.getAgedmallPromoteSettlement();
             for(AgedmallPromoteTemplate aps : agedmallPromoteSettlementList){
                     //支付
                     if(aps.getSettlementType() == PromoteOrderSettlementType.PROMOTE_ORDER_TYPE_1){
                         Integer orderStatus = PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_0;
                         //售卖商品
                         if(aps.getGoodsType().equals(PromoteOrderGoodsType.GOODS_TYPE_SALE)){
                             Long days = PromoteGoodsDays.PROMOTE_GOODS_DAY_0;
                             if(aps.getConfirmTime() != null){
                                 days = this.calculateDays(aps.getConfirmTime());
                             }
                             //判断是否确认收货
                             if(days < PromoteGoodsDays.PROMOTE_GOODS_DAY_15){//判断是否小于15天
                                 orderStatus = PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_2;//未生效
                                 logger.info("订单编号=" + aps.getSmallNumber() + " 的推广订单目前未生效");
                             }
                         }
                     //表示租凭商品
                         if(aps.getGoodsType().equals(PromoteOrderGoodsType.GOODS_TYPE_LEASE)){
                           //查询是否有归还信息
                             if(aps.getReturnCount() == null || aps.getReturnTime() == null){
                                 orderStatus = PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_2;//未生效
                                 logger.info("订单编号=" + aps.getSmallNumber() + " 的推广订单目前未生效");
                             }
                         }
                         this.insert(getAgedmallCustomTemplate(aps),aps,orderStatus);
                     }
             }
    }

    /***
     * 查询订单信息
     * @param agedmallPromoteSettlementList
     * @return
     */
    private List<LitemallUserPromotOrderItem> getVisitUserItemsId(List<AgedmallPromoteTemplate> agedmallPromoteSettlementList){
        Set<Integer> visitUserSet = new HashSet<>();
        Set<Integer> itemsIdSet = new HashSet<>();
        for(AgedmallPromoteTemplate apt : agedmallPromoteSettlementList){
            visitUserSet.add(apt.getVisitUserId());
            itemsIdSet.add(apt.getItemsId());
        }
        //根据商品id和用户id查询下单信息
        List<LitemallUserPromotOrderItem> litemallUserOrderItemList =
                litemallUserPromoteOrderItemMapper.getUserPromoteOrderItemList(visitUserSet, itemsIdSet);
        return litemallUserOrderItemList;
    }


    /**
     * 设置方案信息
     * @param aps
     * @return
     */
    private AgedmallCustomTemplate getAgedmallCustomTemplate(AgedmallPromoteTemplate aps){
        AgedmallCustomTemplate agedmallCustomTemplate = new AgedmallCustomTemplate();
        agedmallCustomTemplate.setDivideType(aps.getDivideType());
        agedmallCustomTemplate.setConsumptionType(aps.getConsumptionType());
        agedmallCustomTemplate.setConsumptionPrice(aps.getConsumptionPrice());
        return agedmallCustomTemplate;
    }


    /**
     * 判断商品是否签收或是否归还成功
     */
    @Scheduled(cron = PromoteScheduled.PROMOTE_REAL_TIOME_OBTAIN_5) // 间隔5秒执行(测试使用)
    @Transactional
    public void confirmGoods(){
        logger.info("系统开启定时任务检查推广订单是否签收或归还");
        //查询没有生效的信息
        AgedmallPromoteUserSettlementExample userSettlementExample = new AgedmallPromoteUserSettlementExample();
        userSettlementExample.or().andStatusEqualTo(PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_2);//未生效
        List<AgedmallPromoteUserSettlement> promoteUserSettlementList =
                          agedmallPromoteUserSettlementMapper.selectByExample(userSettlementExample);
        for(AgedmallPromoteUserSettlement aps : promoteUserSettlementList){
            if(aps.getGoodsType().equals(PromoteOrderGoodsType.GOODS_TYPE_SALE)){
                LitemallOrderItem litemallOrderItem =
                        litemallUserOrderItemMapper.getsalePromoteInfo(aps.getGoodId(),aps.getItemsid(),aps.getGoodsType());
                if(litemallOrderItem != null){
                    //判断时间是否大于15天以上
                    Long days = PromoteGoodsDays.PROMOTE_GOODS_DAY_0;
                    if(litemallOrderItem.getConfirmTime() != null){
                        days = this.calculateDays(litemallOrderItem.getConfirmTime());
                    }
                    //如果商品确认时间小于15天，并且有退货，将状态改为失效
                    if(days < PromoteGoodsDays.PROMOTE_GOODS_DAY_15 && litemallOrderItem.getRefundTime() != null){
                        //将状态修改为失效
                        aps.setStatus(PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_3);//表示失效
                        logger.info("订单 ID=" + aps.getItemsid() + " 的推广订单目前失效");
                    }else if(days >= PromoteGoodsDays.PROMOTE_GOODS_DAY_15 ){
                        aps.setStatus(0);//表示待结算
                        logger.info("订单 ID=" + aps.getItemsid() + " 的推广订单目前待结算");
                    }
                }
            }else if(aps.getGoodsType().equals(PromoteOrderGoodsType.GOODS_TYPE_LEASE)){//表示租赁商品
                //根据订单分成流水表id查询
                AgedmallPromoteSettlement promoteSettlement = agedmallPromoteSettlementMapper.selectByPrimaryKey(aps.getSettlementId());
                //查询是否有归还信息
                AgedmallLeaseGoodsReturnRecordExample goodsReturnRecordExample = new AgedmallLeaseGoodsReturnRecordExample();
                goodsReturnRecordExample.or()
                        .andBigOrderIdEqualTo(String.valueOf(promoteSettlement.getBigorderid()))
                        .andSubOrderIdsEqualTo(String.valueOf(promoteSettlement.getItemsId()));
                AgedmallLeaseGoodsReturnRecord goodsReturnRecord = agedmallLeaseGoodsReturnRecordMapper.selectOneByExample(goodsReturnRecordExample);
                if(goodsReturnRecord != null){
                    aps.setStatus(PromoteOrderSettlementType.PROMOTE_ORDER_TAKE_EFFECT_0);//表示待结算
                    logger.info("订单 ID=" + aps.getItemsid() + " 的推广订单目前待结算");
                }
            }
            agedmallPromoteUserSettlementMapper.updateByPrimaryKey(aps);
        }
    }


    /**
     * 每月10号定时结算上个月佣金
     */
    @Scheduled(cron = PromoteScheduled.PROMOTE_ORDER_SETTLEMENT_05) //间隔5秒执行(测试使用)
    @Transactional
    public void brokerage(){
        logger.info("系统开启定时任务检查推广订单每月10号结算上个月订单信息");
        //查询状态为待结算的数据
        List<AgedmallPromoteUserSettlement> promoteUserSettlementList = agedmallInfoPromoteUserSettlementMapper.getPromoteUserSettlementMonth(getLastMonth());
        for(AgedmallPromoteUserSettlement apus : promoteUserSettlementList){
            AgedmallPromoteAccount agedmallPromoteAccount = new AgedmallPromoteAccount();
            agedmallPromoteAccount.setUserId(apus.getUserId());
            agedmallPromoteAccount.setAccountBalance(apus.getCommission());
            agedmallPromoteAccount.setAddTime(LocalDateTime.now());
            if(apus.getShopId() != null){
                agedmallPromoteAccount.setShopId(Integer.parseInt(apus.getShopId()));//店铺id
            }
            if(apus.getPlanId() != null){
                agedmallPromoteAccount.setPlanId(apus.getPlanId());//方案id
            }
            if(apus.getStoresId() != null){
                agedmallPromoteAccount.setStoresId(apus.getStoresId());//门店id
            }
            agedmallPromoteAccountMapper.insert(agedmallPromoteAccount);
            logger.info("订单 ID=" + apus.getItemsid() + " 的推广订单目前增加到结算表中");
            //修改用户账户总金额
           AgedmallUserInfoExample userInfoExample = new AgedmallUserInfoExample();
           userInfoExample.or().andUserIdEqualTo(apus.getUserId());
           AgedmallUserInfo agedmallUserInfo = agedmallUserInfoMapper.selectOneByExample(userInfoExample);
           if(agedmallUserInfo != null){
               //原有账号金额
               BigDecimal balance = agedmallUserInfo.getAgentAmount();
               agedmallUserInfo.setAgentAmount(balance.add(agedmallPromoteAccount.getAccountBalance()));
               agedmallUserInfoMapper.updateByPrimaryKey(agedmallUserInfo);
               logger.info("结算用户 ID=" + agedmallUserInfo.getUserId()+ " 的分成金额为:"+agedmallPromoteAccount.getAccountBalance());
           }
            apus.setStatus(PromoteOrderSettlementType.PROMOTE_ORDER_SETTLEMENT_TYPE_1.intValue());//已结算
            apus.setWithdrwalTime(LocalDateTime.now());
            agedmallPromoteUserSettlementMapper.updateByPrimaryKey(apus);
            //增加到收支明细表中
            AgedmallAgentFinanceDetail agentFinanceDetail = new AgedmallAgentFinanceDetail();
            agentFinanceDetail.setUserId(apus.getUserId());
            agentFinanceDetail.setType(Byte.parseByte(PromoteOrderSettlementType.PROMOTE_ORDER_INCOME_1));//收入
            agentFinanceDetail.setAmount(apus.getCommission());
            agentFinanceDetail.setAddTime(LocalDateTime.now());
            agentFinanceDetail.setDeleted(false);
            agedmallAgentFinanceDetailMapper.insert(agentFinanceDetail);
            logger.info("结算用户 ID=" + apus.getUserId()+ " 的收支明细为:"+PromoteOrderSettlementType.PROMOTE_ORDER_INCOME_1+apus.getCommission());
        }
    }

    private void insert(AgedmallCustomTemplate agedmallCustomTemplate,AgedmallPromoteTemplate aps,Integer status){
        if (agedmallCustomTemplate.getDivideType() == PromoteDivideType.PROMOTE_DIVIDE_TYPE_1) {//按商品的设置分成(比例和固定值从商品那里查询)
             AgedmallCustomGoods agedmallCustomGoods = new AgedmallCustomGoods();
             agedmallCustomGoods.setConsumptionType(aps.getCustomGoodsType());
             agedmallCustomGoods.setConsumptionPrice(aps.getCustomGoodsPrice());
             this.goodsPriceCalculatorPay(aps,agedmallCustomGoods,status);
        }else if (agedmallCustomTemplate.getDivideType() == PromoteDivideType.PROMOTE_DIVIDE_TYPE_2) {//按消费金额百分比(比例和固定值从方案那里查询)
             this.getAmountProportion(aps,agedmallCustomTemplate,status);
        }
    }

    /**
     * 计算相差天数
     * @param confirmTime
     * @return
     */
    private Long calculateDays(LocalDateTime confirmTime){
        Duration duration = Duration.between(confirmTime,LocalDateTime.now());
        long days = duration.toDays();
        return days;
    }


    /**
     * 按金额比例
     * @param
     * @param aps
     * @return
     */
    private BigDecimal getAmountProportion(AgedmallPromoteTemplate aps,
                                           AgedmallCustomTemplate agedmallCustomTemplate,Integer status){
        BigDecimal dividedpriceCount = BigDecimal.ZERO;
        BigDecimal profitsPrice = this.getProfitsPrice(aps);
        //获取比例值或者固定值
        BigDecimal proportionValue = agedmallCustomTemplate.getConsumptionPrice();
        if(agedmallCustomTemplate.getConsumptionType() == PromoteDivideType.PROMOTE_DIVIDE_PROPORTION){//按推广分成比例
           BigDecimal percentage = this.getPercentage(proportionValue);
           BigDecimal profitsPriceCount = profitsPrice.multiply(percentage);
           if(profitsPriceCount.compareTo(BigDecimal.ZERO) > 0){
               dividedpriceCount = profitsPriceCount;
           }
        }else if(agedmallCustomTemplate.getConsumptionType() == PromoteDivideType.PROMOTE_DIVIDE_FIXED_AMOUNT){//固定金额
            //计算分成价格
            BigDecimal dividedprice = profitsPrice.subtract(profitsPrice.subtract(proportionValue));
            if (dividedprice.compareTo(BigDecimal.ZERO) > 0) {
                dividedpriceCount = dividedprice;
            }
        }
        //将信息添加到用户结算表中
        this.insertPromoteUserSettlement(aps, dividedpriceCount, aps.getGoodId().toString(),status);
        //修改订单结算表状态(根据)
        this.updatePromoteSettlement(aps);
        return dividedpriceCount;
    }

    /**
     * 计算百分比
     * @param bigDecimal
     * @return
     */
    private BigDecimal getPercentage(BigDecimal bigDecimal){
        //计算比较百分比
        BigDecimal numerical = BigDecimal.valueOf(0.01);
        BigDecimal percentage = bigDecimal.multiply(numerical).setScale(2,BigDecimal.ROUND_HALF_UP);
        return percentage;
    }

    /**
     * 获取商品利润价格-运费价格(支付)
     * @param
     * @return
     */
    private BigDecimal getProfitsPrice(AgedmallPromoteTemplate aps){
        //实际支付价格
        BigDecimal payPrice = aps.getActualPrice();
        //运费价格
        BigDecimal freightPrice = aps.getFreightPrice();
        //计算商品价格
        BigDecimal goodPrice = payPrice.subtract(freightPrice);
        //计算利润价格
        LitemallGoods litemallGoods = this.getLitemallGoods(aps.getGoodId().toString());
        BigDecimal profitsPrice = goodPrice.subtract(litemallGoods.getCounterPrice());
        return profitsPrice;
    }

    /**
     * 按商品的设置分成
     * @param
     * @return
     */
    private BigDecimal goodsPriceCalculatorPay(AgedmallPromoteTemplate aps,
                                               AgedmallCustomGoods agedmallCustomGoods,Integer status){
        BigDecimal dividedpriceCount = new BigDecimal(0);
        BigDecimal profitsPrice = this.getProfitsPrice(aps);
        if (agedmallCustomGoods.getConsumptionType() == PromoteDivideType.PROMOTE_GOODS_PROPORTION) {//商品的按比例分成
            BigDecimal percentage = this.getPercentage(agedmallCustomGoods.getConsumptionPrice());
            dividedpriceCount = profitsPrice.multiply(percentage);
        } else if (agedmallCustomGoods.getConsumptionType() == PromoteDivideType.PROMOTE_GOODS_FIXED_AMOUNT) {//商品的按固定金额
            //计算分成价格
            BigDecimal dividedprice = profitsPrice.subtract(profitsPrice.subtract(agedmallCustomGoods.getConsumptionPrice()));
            if (dividedprice.compareTo(BigDecimal.ZERO) > 0) {
                dividedpriceCount = dividedprice;
            }
        }
         this.addBillingInfo(aps,dividedpriceCount,status);
        return dividedpriceCount;
    }

    /**
     * 增加结算信息
     * @param aps
     * @param dividedpriceCount
     */
    private void addBillingInfo(AgedmallPromoteTemplate aps,BigDecimal dividedpriceCount,Integer status){
        //将信息添加到用户结算表中
        this.insertPromoteUserSettlement(aps, dividedpriceCount, aps.getGoodId().toString(),status);
        //修改订单结算表状态(根据)
        this.updatePromoteSettlement(aps);
    }

    /**
     * 查询分成信息
     * @param aps
     */
    private AgedmallCustomGoods  getCustomGoodsExample(AgedmallPromoteTemplate aps){
        AgedmallCustomGoodsExample customGoodsExample = new AgedmallCustomGoodsExample();
        customGoodsExample.or()
                .andGoodsIdEqualTo(Integer.valueOf(aps.getGoodId()))
                .andDeletedEqualTo(false);
        AgedmallCustomGoods agedmallCustomGoods = agedmallCustomGoodsMapper.selectOneByExample(customGoodsExample);
        return agedmallCustomGoods;
    }

    /**
     * 修改订单结算表状态
     * @param aps
     */
    private void updatePromoteSettlement(AgedmallPromoteTemplate aps){
        AgedmallPromoteSettlement promoteSettlement = new AgedmallPromoteSettlement();
        promoteSettlement.setId(aps.getId());
        promoteSettlement.setSettlementStatus(PromoteOrderSettlementType.PROMOTE_ORDER_SETTLEMENT_TYPE_1);//设置为已结算
        agedmallPromoteSettlementMapper.updateByPrimaryKeySelective(promoteSettlement);
    }

    /**
     * 增加用户结算表
     * @param agedmallPromoteSettlement
     * @param dividedprice
     * @param goodId
     */
    private void insertPromoteUserSettlement(AgedmallPromoteTemplate agedmallPromoteSettlement,
                                             BigDecimal dividedprice,
                                             String goodId,
                                             Integer status){
        AgedmallPromoteUserSettlement promoteUserSettlement = new AgedmallPromoteUserSettlement();
        promoteUserSettlement.setUserId(agedmallPromoteSettlement.getPromoteId());
        promoteUserSettlement.setSettlementId(agedmallPromoteSettlement.getId());
        promoteUserSettlement.setCommission(dividedprice);
        promoteUserSettlement.setAddTime(LocalDateTime.now());
        promoteUserSettlement.setWithdrawalState(PromoteCashType.PROMOTE_CASH_0);//是否提现(0:否 1:是)
        promoteUserSettlement.setGoodId(Integer.valueOf(goodId));
        promoteUserSettlement.setStatus(status);//0:待结算 1:已结算 2:未生效 3:已失效
        promoteUserSettlement.setGoodsType(agedmallPromoteSettlement.getGoodsType());
        promoteUserSettlement.setItemsid(agedmallPromoteSettlement.getItemsId());//小订单id
        if(agedmallPromoteSettlement.getShopId() != null){
            promoteUserSettlement.setShopId(agedmallPromoteSettlement.getShopId());//店铺id
        }
        if(agedmallPromoteSettlement.getPlanId() != null){
            promoteUserSettlement.setPlanId(agedmallPromoteSettlement.getPlanId());//方案id
        }
        if(agedmallPromoteSettlement.getStoresId() != null){
            promoteUserSettlement.setStoresId(agedmallPromoteSettlement.getStoresId());//店铺id
        }
        agedmallPromoteUserSettlementMapper.insertSelective(promoteUserSettlement);
    }

    /**
     * 查询商品信息
     * @param goodId
     * @return
     */
    private LitemallGoods getLitemallGoods(String goodId){
        LitemallGoods litemallGoods = litemallGoodsMapper.selectByPrimaryKey(Integer.parseInt(goodId));
        return litemallGoods;
    }

    /**
     * 获取上个月的信息
     * @return
     */
    private String getLastMonth() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        String accDate = format.format(date);
        return accDate;
    }
}
